from django.db import models
from django.template.defaultfilters import slugify
from django.db import IntegrityError, transaction

class NameSlugModel(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, editable=False)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        """
        Based on the Tag save() method in django-taggit, this method simply
        stores a slugified version of the name, ensuring that the unique
        constraint is observed
        """

        self.slug = slug = slugify(self.name)
        i = 0
        while True:
            try:
                savepoint = transaction.savepoint()
                res = super(NameSlugModel, self).save(*args, **kwargs)
                transaction.savepoint_commit(savepoint)
                return res
            except IntegrityError:
                transaction.savepoint_rollback(savepoint)
                i += 1
                self.slug = '%s_%d' % (slug, i)
